package app.qrcode.browser.todoapp.common

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.activity.addCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType
import androidx.annotation.IdRes

/**
 * Created by YiGo on 2022/9/14.
 */
abstract class ViewBindingFragment<T : ViewBinding> : Fragment() {

    private var _binding: T? = null
    protected val binding get() = _binding!!

    open fun initView() = Unit
    open fun initEvent() = Unit

    open fun getNavigateId(): Int = 0
    protected open val enabledBack = false

    @Suppress("UNCHECKED_CAST")
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val type = javaClass.genericSuperclass as ParameterizedType
        val cls = type.actualTypeArguments[0] as Class<*>
        val inflate = cls.getDeclaredMethod(
            "inflate",
            LayoutInflater::class.java,
            ViewGroup::class.java,
            Boolean::class.java
        )
        _binding = inflate.invoke(null, inflater, container, false) as T
        return binding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
        initEvent()
    }

    open fun navigate(@IdRes resId: Int, args: Bundle? = null) {
        val navController = findNavController()
        val currentDestination = navController.currentDestination
        if (getNavigateId() == 0 || currentDestination?.id == getNavigateId()) {
            navController.navigate(resId, args)
        }
    }

    protected fun setupToolbar(toolbar: Toolbar, showBack: Boolean = false) {
        (activity as AppCompatActivity).also {
            it.setSupportActionBar(toolbar)
            it.supportActionBar?.apply {
                setDisplayShowTitleEnabled(false)
                setDisplayHomeAsUpEnabled(showBack)
            }
        }
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        requireActivity().onBackPressedDispatcher.addCallback(this, enabledBack) {
            onBackPressed()
        }
    }

    protected open fun onBackPressed() {
        val r = findNavController().popBackStack()
        if (!r) {
            requireActivity().finish()
        }
    }
}
